package com.es.test.service;


import co.elastic.clients.elasticsearch.ElasticsearchAsyncClient;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch._types.mapping.TypeMapping;
import co.elastic.clients.elasticsearch.core.BulkRequest;
import co.elastic.clients.elasticsearch.core.IndexRequest;
import co.elastic.clients.elasticsearch.core.ScrollRequest;
import co.elastic.clients.elasticsearch.core.ScrollResponse;
import co.elastic.clients.elasticsearch.indices.CreateIndexRequest;
import co.elastic.clients.elasticsearch.indices.IndexSettings;
import co.elastic.clients.elasticsearch.indices.put_index_template.IndexTemplateMapping;
import co.elastic.clients.elasticsearch.transform.Settings;
import co.elastic.clients.json.JsonpMapper;
import co.elastic.clients.util.ObjectBuilder;
import com.alibaba.excel.util.IoUtils;
import com.alibaba.fastjson2.JSON;
import jakarta.json.stream.JsonParser;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.nio.file.Files;
import java.nio.file.Paths;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.function.Function;

@Service
public class UserAsyncService {
    @Autowired
    private ElasticsearchAsyncClient elasticsearchAsyncClient;
    @Autowired
    private ElasticsearchClient elasticsearchClient;

    public void bulk(BulkRequest request) {
        elasticsearchAsyncClient.bulk(request);
    }

    public void index() throws IOException {
       /* Reader settingReader = new StringReader(" ");
        elasticsearchAsyncClient.index(builder -> builder.index("label_a").withJson(settingReader));*/
        // 创建 Settings.Builder
        Settings.Builder settingsBuilder = new Settings.Builder();

        // JSON 格式的设置字符串
        String jsonSettings = "{" +
                "\"index.number_of_shards\": 3," +
                "\"index.number_of_replicas\": 2" +
                // 其他设置...
                "}";


        // 使用自定义的 JSON 解析器和映射器
        settingsBuilder.withJson(new StringReader(jsonSettings));

        CreateIndexRequest.Builder createIndexRequest = new CreateIndexRequest.Builder();

        IndexSettings.Builder is = new IndexSettings.Builder();
        is.shards(3);
        is.refreshInterval(t -> t.time("10s"));
        createIndexRequest.settings(is.build());

        IndexTemplateMapping.Builder itm = new IndexTemplateMapping.Builder();
  /*
       createIndexRequest.mapping("{ \"properties\": { \"field1\": { \"type\": \"text\" } } }", "application/json");
        Map<String, Object> mapping = new HashMap<>();
     mapping.put("properties", Map.of(
                "field1", Map.of("type", "text")
        ));
                mapping.put("properties", new HashMap<>());

        */

         // tb这里补全



       /* XContentBuilder mapping = XContentBuilder.builder(XContentType.JSON.xContent())
                .startObject()
                .startObject("properties")
                .startObject("name")
                .field("type", "text")
                .endObject()
                .endObject()
                .endObject();*/

        // 在此设置 TypeMapping 的属性，如字段类型等
        TypeMapping.Builder tb = new TypeMapping.Builder();
         createIndexRequest.mappings(tb.build());


        elasticsearchAsyncClient.indices().create(createIndexRequest.build());
    }

    public void index3(){
         JsonpMapper mapper = elasticsearchAsyncClient._transport().jsonpMapper();

        InputStream input = this.getClass()
                .getResourceAsStream("/index.json");
        String mappings_str = null;
        try {
            mappings_str = new String(IoUtils.toByteArray(input));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        System.out.println("mappings are: " +  mappings_str);
        JsonParser parser = mapper.jsonProvider()
                .createParser(new StringReader( mappings_str ));

        elasticsearchAsyncClient.indices()
                .create(createIndexRequest -> createIndexRequest.index("test")
                        .mappings(TypeMapping._DESERIALIZER.deserialize(parser, mapper)));
    }


    public void createIndex(){


        Map<String, Object> mappingMap = new HashMap<>();
        Map<String, Object> mappings = new HashMap<>();
        Map<String, Object> properties = new HashMap<>();
        mappingMap.put("mappings", mappings);
        mappings.put("properties", properties);
        for (int i = 0; i < 3; i++) {
            HashMap<String, Object> typeMap = new HashMap<>();
            typeMap.put("type", "keyword");
            properties.put("name_" + i, typeMap);
        }

         Map<String, Object> settingsIndexMap = new HashMap<>();
        Map<String, Object> settingsIndexValueMap = new HashMap<>();
        settingsIndexValueMap.put("number_of_shards", 3);
        settingsIndexValueMap.put("number_of_replicas", 2);
        settingsIndexValueMap.put("refresh_interval", "5s");
        settingsIndexMap.put("index", settingsIndexValueMap);
        mappingMap.put("settings", settingsIndexMap);



        Map<String, Object> dynamicTemplatesMap = new HashMap<>();
        mappings.put("dynamic_templates", dynamicTemplatesMap);
        Map<String, Object> stringsAskeywordMap = new HashMap<>();
         dynamicTemplatesMap.put("strings_as_keyword", stringsAskeywordMap);
        stringsAskeywordMap.put("match_mapping_type", "string");
        Map<String, Object> mapingMap = new HashMap<>();
        mapingMap.put("type", "keyword");
        stringsAskeywordMap.put("mapping", mapingMap);

        String jsonString = JSON.toJSONString(mappingMap);
        System.out.println(JSON.toJSONString(mappingMap));
        CreateIndexRequest.Builder createIndexRequestBuilder = new CreateIndexRequest.Builder();
        createIndexRequestBuilder.withJson(new StringReader(jsonString));

        createIndexRequestBuilder.index("label_test");
        CreateIndexRequest createIndexRequest = createIndexRequestBuilder.build();

        elasticsearchAsyncClient.indices().create(createIndexRequest);
    }

    public void index4(){
        JsonpMapper mapper = elasticsearchAsyncClient._transport().jsonpMapper();

        InputStream input = this.getClass()
                .getResourceAsStream("/index.json");
        String mappings_str = null;
        try {
            mappings_str = new String(IoUtils.toByteArray(input));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }


        CreateIndexRequest.Builder createIndexRequestBuilder = new CreateIndexRequest.Builder();

        createIndexRequestBuilder.withJson(new StringReader( mappings_str ));
        createIndexRequestBuilder.index("test");
        CreateIndexRequest createIndexRequest = createIndexRequestBuilder.build();

        elasticsearchAsyncClient.indices().create(createIndexRequest);
    }

    public void index1() {
        InputStream input = this.getClass()
                .getResourceAsStream("/index.json");

        CreateIndexRequest req = CreateIndexRequest.of(b -> b
                .index("some-index")
                .withJson(input)
        );

        boolean created = elasticsearchAsyncClient.indices().create(req).isCancelled();
    }

    public <TDocument> ScrollResponse<TDocument> scroll(
            Function<ScrollRequest.Builder, ObjectBuilder<ScrollRequest>> fn, Class<TDocument> tDocumentClass) {
        CompletableFuture<ScrollResponse<TDocument>> future = elasticsearchAsyncClient.scroll(fn, tDocumentClass);
        future.whenCompleteAsync((response, exception) -> {
            String scrollId = response.scrollId();
            if (exception != null) {
            } else {
            }
        });
        try {
            return future.get();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        }
    }
}
